/*
 * Alloy Analyzer
 * Copyright (c) 2002 Massachusetts Institute of Technology
 *
 * The Alloy Analyzer is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * The Alloy Analyzer is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with the Alloy Analyzer; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package alloy.ast;

import java.util.HashMap;
import java.util.Map;

public class Module extends TreeNode {

    /**
     * index of name in child list
     */
    private static final int NAME_INDEX = 0;

    /**
     * index of signatures in child list
     */
    private static final int SIGNATURES_INDEX = 1;

    /**
     * index of facts in child list
     */
    private static final int FACTS_INDEX = 2;

	/**
	 * index of predicates in child list
	 */
    private static final int PREDICATES_INDEX = 3;

    /**
     * index of functions in child list
     */
    private static final int FUNCTIONS_INDEX = 4;

    /**
     * index of assertions in child list
     */
    private static final int ASSERTIONS_INDEX = 5;

    /**
     * index of commands in child list
     */
    private static final int COMMANDS_INDEX = 6;

    /**
     * index of used Modules in child list
     */
    private static final int USEDMODULES_INDEX = 7;

    /**
     * index of opened Modules in child list
     */
    private static final int OPENEDMODULES_INDEX = 8;
    
    /**
     * index of polymorphic parameters in child list
     */
    private static final int POLYPARAMS_INDEX = 9;
	
    /**
     * mapping of aliases to module names
     * there is no null alias that points to this module
     */
    private Map _aliasesToModuleNames = new HashMap();

    /**
     * information about this
     * @see ModuleInfo
     * @see alloy.semantic.MakeModuleScopesVisitor
     */
    private ModuleInfo _info;

    public Module(Location location_, QualifiedName name_, Signatures signatures_, Facts facts_, Predicates predicates_, Functions functions_, Assertions assertions_,
		  Commands commands_, QualifiedNames usedModules_, QualifiedNames openedModules_, QualifiedNames polyParams_) {
        super(location_, name_, signatures_, facts_, predicates_, functions_, assertions_);
        // don't feel like adding another constructor just for this class
        addChild(commands_);
        addChild(usedModules_);
        addChild(openedModules_);
        addChild(polyParams_);
    }


    public Module(QualifiedName name_, Signatures signatures_, Facts facts_, Predicates predicates_, Functions functions_, Assertions assertions_,
		  Commands commands_, QualifiedNames usedModules_, QualifiedNames openedModules_, QualifiedNames polyParams_) {
        super(Location.UNKNOWN, name_, signatures_, facts_, predicates_, functions_, assertions_);
        // don't feel like adding another constructor just for this class
        addChild(commands_);
        addChild(usedModules_);
        addChild(openedModules_);
        addChild(polyParams_);
    }



    //GET AND SET METHODS

    /**
     * gets the name of this
     * @return the {@link QualifiedName}
     */
    public QualifiedName getName() {
        return (QualifiedName)childAt(NAME_INDEX);
    }

    /** set the Name of this */
    public void setName(QualifiedName newChild_) {
        setChild(NAME_INDEX, newChild_);
    }

    /**
     * gets the signatures of this
     * @return the {@link Signatures}
     */
    public Signatures getSignatures() {
        return (Signatures)childAt(SIGNATURES_INDEX);
    }

    /** set the Signatures of this */
    public void setSignatures(Signatures newChild_) {
        setChild(SIGNATURES_INDEX, newChild_);
    }

    /**
     * gets the facts of this
     * @return the {@link Facts}
     */
    public Facts getFacts() {
        return (Facts)childAt(FACTS_INDEX);
    }

    /** set the Facts of this */
    public void setFacts(Facts newChild_) {
        setChild(FACTS_INDEX, newChild_);
    }

	/**
	 * gets the predicates of this
	 * @return the {@link Predicates}
	 */
	public Predicates getPredicates() {
		return (Predicates)childAt(PREDICATES_INDEX);
	}

	/** set the Predicates of this */
	public void setPredicates(Predicates newChild_) {
		setChild(PREDICATES_INDEX, newChild_);
    }

    /**
     * gets the functions of this
     * @return the {@link Functions}
     */
    public Functions getFunctions() {
        return (Functions)childAt(FUNCTIONS_INDEX);
    }

    /** set the Functions of this */
    public void setFunctions(Functions newChild_) {
        setChild(FUNCTIONS_INDEX, newChild_);
    }

    /**
     * gets the assertions of this
     * @return the {@link Assertions}
     */
    public Assertions getAssertions() {
        return (Assertions)childAt(ASSERTIONS_INDEX);
    }

    /** set the Assertions of this */
    public void setAssertions(Assertions newChild_) {
        setChild(ASSERTIONS_INDEX, newChild_);
    }

    /**
     * gets the commands of this
     * @return the {@link Commands}
     */
    public Commands getCommands() {
        return (Commands)childAt(COMMANDS_INDEX);
    }

    /** set the Commands of this */
    public void setCommands(Commands newChild_) {
        setChild(COMMANDS_INDEX, newChild_);
    }

    /**
     * gets the used Modules of this
     * @return the {@link QualifiedNames}
     */
    public QualifiedNames getUsedModules() {
        return (QualifiedNames)childAt(USEDMODULES_INDEX);
    }

    /** set the UsedModules of this */
    public void setUsedModules(QualifiedNames newChild_) {
        setChild(USEDMODULES_INDEX, newChild_);
    }

    /**
     * gets the opened Modules of this
     * @return the {@link QualifiedNames}
     */
    public QualifiedNames getOpenedModules() {
        return (QualifiedNames)childAt(OPENEDMODULES_INDEX);
    }

    /** set the OpenedModules of this */
    public void setOpenedModules(QualifiedNames newChild_) {
        setChild(OPENEDMODULES_INDEX, newChild_);
    }
    
    /**
     * gets the polymorphic parameters of this
     * @return the {@link QualifiedNames}
     */
    public QualifiedNames getPolyParams() {
    	return (QualifiedNames)childAt(POLYPARAMS_INDEX);
    }
    
	/** set the PolyParams of this */
	public void setPolyParams(QualifiedNames newChild_) {
		setChild(POLYPARAMS_INDEX, newChild_);
	}

    /** set the info of this */
    public void setModuleInfo(ModuleInfo info_) {
        _info = info_;
    }

    /** get the info of this */
    public ModuleInfo getModuleInfo() {
        return _info;
    }
    
    public void setAliasMappings(Map aliasesToModuleNames_) {
    	_aliasesToModuleNames = aliasesToModuleNames_;
    }

    public Map getAliasMappings() {
	return _aliasesToModuleNames;
    }


    /**
     * accept an AST visitor
     * @param visitor_ the visitor
     */
    protected void acceptVisitor(ASTVisitor visitor_) {
        visitor_.visit(this);
    }

    /**
     * accept a returning AST visitor
     * @param visitor_ the visitor
     * @return the Object returned by the visitor
     */
    protected Object acceptReturnVisitor(ASTReturnVisitor visitor_) {
        return visitor_.visit(this);
    }

    public String nodeString() {
        return "module " + super.nodeString();
    }

    public String toString()
    {
        return "Module: " + getName().toString();
    }
}
